#include "ItemDrop.h"


namespace
{
	const DropCfg* GetDropCfg(uint32 dropid) { return nullptr; }
	template<typename T, std::size_t N>
	constexpr std::size_t ArrayLen(T(&)[N])
	{ // constexpr
		return N; // and
	}
}

std::map<uint32, uint32> DropDevice::Drop(uint32 dropid, uint32 num /*= 1*/)
{
	std::map<uint32, uint32> id2num;
	for (uint32 i=0; i<num; ++i)
	{
		std::map<uint32, uint32> r = DropEx(dropid);
		id2num.insert(r.begin(), r.end());
		if (m_filter)
		{
			m_filter(id2num);
		}
	}
	std::map<uint32, uint32> lastRecursionId2Num; //保存继续递归掉落的最终物品

	for (auto it = id2num.begin(); it != id2num.end(); )
	{
		if (IsDropId(it->first))
		{
			std::map<uint32, uint32> r = Drop(it->first, it->second);//recursion call
			for (auto& v : r)
			{
				lastRecursionId2Num[v.first] += v.second;
			}
			it = id2num.erase(it);
		}
		else
		{
			++it;
		}
	}
	for (auto& v : lastRecursionId2Num)
	{
		id2num[v.first] += v.second;
	}
	return id2num;
}

std::map<uint32, uint32> DropDevice::DropEx(uint32 dropid)
{
	std::map<uint32, uint32> id2num;

	const DropCfg* cfg = GetDropCfg(dropid);
	if (nullptr == cfg)
	{
		return id2num;
	}
	if (cfg->bfix)//固定掉落
	{
		for (uint32 i=0; i<ArrayLen(cfg->itemid); ++i)
		{
			id2num[cfg->itemid[i]] = cfg->num[i];
		}
		return id2num;
	}
	else //概率掉落
	{
		std::vector<uint32> vecWeight;
		std::vector<uint32> vecCfgId; 
		for (uint32 i = 0; i < ArrayLen(cfg->itemid); ++i)
		{
			vecWeight.push_back(cfg->weight[i]);
			vecCfgId.push_back(cfg->itemid[i]);
		}
		uint32_t idx = RandomWeight::rand(vecWeight);
		int32_t randCfgId = vecCfgId[idx];

		id2num[randCfgId] = cfg->num[idx];
		return id2num;
	}
}

bool DropDevice::IsDropId(uint32 dropid)
{
	return false;
}
